package com.boyon.system.service;

import java.util.List;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.boyon.common.exection.BusinessException;
import com.boyon.common.status.AccountType;
import com.boyon.common.status.MenuType;
import com.boyon.common.status.StatusType;
import com.boyon.common.status.SystemType;
import com.boyon.common.tools.ObjectTool;
import com.boyon.common.tools.StringTool;
import com.boyon.hbm.criteria.OperationType;
import com.boyon.hbm.criteria.Param;
import com.boyon.hbm.criteria.Query;
import com.boyon.service.AbstractService;
import com.boyon.system.assembly.MenuAssembly;
import com.boyon.system.entity.Menu;
import com.boyon.system.entity.RoleManager;

/**
 * ClassName:MenuService <br/>
 * Function: 菜单service. <br/>
 * Date: 2018年3月14日 下午11:46:41 <br/>
 * 
 * @author sunshulin
 * @version
 * @since JDK 1.8
 * @see
 */
@Service
public class MenuService extends AbstractService {

	@Autowired
	private MenuAssembly menuAssembly;

	/**
	 * 
	 * query:查询所有菜单不包含删除. <br/>
	 * 
	 * @author sunshulin
	 * @param menuIds菜单id
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public Menu query(Long loginRoleId, Long roleId, List<Long> menuIds,
			AccountType accountType) {
		Query query = new Query();
		query.addParam(new Param<Integer>("status", OperationType.nq,
				StatusType.del.getStatus()));
		if (AccountType.system == accountType) {
			// 当前登录用户系统账号,系统账号设置管理权限,管理权限可以使用管理菜单和用户菜单
			query.addParam(new Param<Integer>("isSystem", OperationType.nq,
					SystemType.system.getVal()));
		} else if (AccountType.manager == accountType) {
			// 当前登录用户管理账号,管理账号设置用户权限,用户权限只能使用用户菜单
			query.addParam(new Param<Integer>("isSystem", OperationType.eq,
					SystemType.user.getVal()));
		} else {
			throw BusinessException.builder(0, "只有系统账号和管理账号可以添加角色");
		}
		List<Menu> list = query(query);
		if (AccountType.manager == accountType) {
			// 当前登录用户管理账号,管理账号使用权限过滤原有权限
			RoleManager roleManager = generalDao.get(RoleManager.class,
					loginRoleId);
			if (ObjectTool.isNotNull(roleManager)
					&& StringTool.isNotNull(roleManager.getMenu())) {
				List<Long> ids = StringTool
						.converStringToLong(roleManager.getMenu().split(","));
				list = filter(list, ids);
			}
		}
		return menuAssembly.createTree(list, menuIds);
	}

	/**
	 * 
	 * findRoleManagerByUserMenu:管理账号定义权限可使用的用户菜单. <br/>
	 * 
	 * @author sunshulin
	 * @param menuIds
	 * @return
	 * @since JDK 1.8
	 */
	public Menu findRoleManagerByUserMenu(List<Long> menuIds) {
		Query query = new Query();
		query.addParam(new Param<Integer>("status", OperationType.nq,
				StatusType.del.getStatus()));
		// 当前登录用户管理账号,管理账号设置用户权限,用户权限只能使用用户菜单
		query.addParam(new Param<Integer>("isSystem", OperationType.eq,
				SystemType.user.getVal()));
		List<Menu> list = query(query);
		return menuAssembly.createTree(list, menuIds);
	}

	/**
	 * 
	 * query:查询所有菜单不包含删除和按钮. <br/>
	 * 
	 * @author sunshulin
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public Menu queryByMenuType() {
		List<Menu> list = queryMenu();
		return menuAssembly.createTree(list);
	}

	/**
	 * 
	 * query:查询菜单. <br/>
	 * 
	 * @author sunshulin
	 * @param query
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public List<Menu> query(Query query) {
		List<Menu> list = generalDao.query(Menu.class, query);
		return list;
	}

	/**
	 * 
	 * query:查询菜单. <br/>
	 * 
	 * @author sunshulin
	 * @param query
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public List<Menu> queryMenu() {
		Query query = new Query();
		query.addParam(new Param<Integer>("status", OperationType.nq,
				StatusType.del.getStatus()));
		query.addParam(new Param<Integer>("menuType", OperationType.eq,
				MenuType.menu.getVal()));
		List<Menu> list = generalDao.query(Menu.class, query);
		return list;
	}

	/**
	 * 
	 * filter:过滤菜单节点. <br/>
	 * 
	 * @author sunshulin
	 * @param menus
	 * @param menuIds
	 * @since JDK 1.8
	 */
	public List<Menu> filter(List<Menu> menus, List<Long> menuIds) {
		return menus.stream().filter(menu -> menuIds.contains(menu.getMenuId()))
				.collect(Collectors.toList());
	}

	/**
	 * 
	 * tree:生成树形结构. <br/>
	 * 
	 * @author sunshulin
	 * @param menus
	 * @return
	 * @since JDK 1.8
	 */
	public Menu tree(List<Menu> menus) {
		return menuAssembly.createTree(menus);
	}
}
